package com.base.controller.czb.czbapi;

import com.alibaba.fastjson.JSONArray;
import com.base.controller.api.RedisCacheManager;
import com.base.controller.utils.CZB.CZBOilUtil;
import com.base.controller.utils.CZB.CZBPayUtils;
import com.base.controller.utils.CZB.CZBTokenUtils;
import com.base.helper.VosHelper;
import com.base.po.czb.GenerateOrder;
import com.base.po.czb.PayRefund;
import com.base.po.czb_sdk.CZBPayToken;
import com.base.po.czb_sdk.Gas;
import com.base.po.czb_sdk.GasOilprice;
import com.base.po.czb_sdk.GasOrder;
import com.base.po.param.InfoCustomers;
import com.base.po.param.NetState;
import com.base.po.param.VosModelList;
import com.base.po.voip.Subscribers;
import com.base.po.voip.Userpays;
import com.base.po.voip.Users;
import com.base.service.CZB.GasOrderService;
import com.base.service.CZB.GasService;
import com.base.service.SubscribersService;
import com.base.service.UserpaysService;
import com.base.service.UsersService;
import com.base.utils.GsonUtil;
import com.base.utils.Page;
import com.base.utils.Produce;
import com.beust.jcommander.internal.Maps;
import io.swagger.annotations.ApiOperation;
import lombok.extern.log4j.Log4j;
import net.sf.json.JSONObject;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Log4j
@Controller
@RequestMapping("/gas")
public class GasOrderController {
    @Autowired
    private UsersService usersService;
    @Autowired
    private SubscribersService subscribersService;
    @Autowired
    private GasService gasService;
    @Autowired
    private GasOrderService gasOrderService;
    @Autowired
    private UserpaysService userpaysService;
    @Autowired
    private RedisCacheManager redisCacheManager;

    @RequestMapping(value = "/generateOrder", method = {RequestMethod.POST, RequestMethod.GET})
    @ApiOperation(value = "api接口", notes = "生成油站订单数据")
    public @ResponseBody
    NetState generateOrder(String userId, String gasId, String oilNo, Integer gunNo, BigDecimal amountGun) {
        NetState netState = new NetState();
        if (userId == null || gasId == null || oilNo == null) {
            netState.setErrorCode(NetState.PARAMS_ERROR);
            netState.setData("参数异常");
            return netState;
        }

        Subscribers sub = subscribersService.selectByPrimaryKey(userId);
        if (sub == null) {
            netState.setErrorCode(NetState.NODATA);
            netState.setData("数据异常");
            return netState;
        }

        // 获取token
        String token = null;
        Long date = Produce.getNowDate().getTime();
        String tokenResult = CZBPayUtils.createTokenAPI(date, sub.getMobile());
        CZBPayToken czbToken = (CZBPayToken) JSONObject.toBean(JSONObject.fromObject(tokenResult), CZBPayToken.class);
        if (czbToken != null && czbToken.getCode() == 200) {
            token = czbToken.getResult().getToken();
        }

        // 油站信息
        Gas gas = gasService.selectByPrimaryKey(gasId);
        //重新获取油站信息
        GasOilprice gasOilprice = CZBOilUtil.getGasDetailApi(sub.getMobile(), sub.getParentid(), gasId, oilNo, token, date);
        if (gasOilprice == null) {
            netState.setErrorCode(NetState.ERROR_OPERATE);
            netState.setData("油站信息查询失败");
        }
        // 油站价格信息
        if (gas != null && gasOilprice != null) {
            // 计算随便打优惠价格
//            BigDecimal sbdPriceYfq = gasOilprice.getPricegun().subtract(gasOilprice.getPriceyfq()).multiply(new BigDecimal(0.1)).add(gasOilprice.getPriceyfq());
            // 计算升数
            BigDecimal litre = amountGun.divide(gasOilprice.getPricegun(), 2, BigDecimal.ROUND_HALF_UP);
//            // 计算随便打实付
//            BigDecimal sbdPayAmount = litre.multiply(sbdPriceYfq).setScale(2, BigDecimal.ROUND_HALF_UP);
            // 计算随便打实付
//            BigDecimal sbdPayAmount = litre.multiply(sbdPriceYfq).setScale(2, BigDecimal.ROUND_HALF_UP);
            // 计算车主帮实付
            BigDecimal czbPayAmount = amountGun.multiply(gasOilprice.getPriceyfq()).divide(gasOilprice.getPricegun(), 2, BigDecimal.ROUND_HALF_UP);
            // 计算随便打实付
            BigDecimal sbdPayAmount = czbPayAmount;

            String orderResult = CZBPayUtils.getGasOrder(Produce.getNowDate().getTime(), token, gasId, gunNo, amountGun.setScale(2, BigDecimal.ROUND_HALF_UP),
                    Produce.getUUID(), gasOilprice.getPricegun().setScale(2, BigDecimal.ROUND_HALF_UP), gasOilprice.getPriceyfq().setScale(2, BigDecimal.ROUND_HALF_UP), litre);
            GenerateOrder order = (GenerateOrder) JSONObject.toBean(JSONObject.fromObject(orderResult), GenerateOrder.class);
            if (order != null && order.getCode() == 500) {
                netState.setErrorCode(NetState.ERROR_OPERATE);
                netState.setData(order.getMessage());
                return netState;
            }

            if (order != null && order.getCode() == 200) {
                GasOrder gasOrder = new GasOrder();
                gasOrder.setId(order.getResult().getOuterOrderId());
                gasOrder.setUserid(userId);
                gasOrder.setCzborderid(order.getResult().getOrderId());
                gasOrder.setCzbouterorderid(order.getResult().getOuterOrderId());
                gasOrder.setCzbordersn(order.getResult().getOrderSn());
                gasOrder.setGasid(gasId);
                gasOrder.setGasname(gas.getGasname());
                gasOrder.setGunno(gunNo.toString());
                gasOrder.setOilname(gasOilprice.getOilname());
                gasOrder.setSbdpayamount(sbdPayAmount);
                gasOrder.setAmountgun(amountGun);
                gasOrder.setCzbpayamount(czbPayAmount);
                gasOrder.setPricegun(gasOilprice.getPricegun());
                gasOrder.setPriceunit(gasOilprice.getPriceyfq());
                gasOrder.setLitre(litre);
                gasOrder.setPaystatus(0);
                gasOrder.setCreatetime(Produce.getNowDate());

                int code = gasOrderService.insertSelective(gasOrder);
                if (code == 1) {
                    netState.setErrorCode(NetState.SUCCESS_CONN);
                    netState.setData("订单生成成功");
                    netState.setJson(order.getResult().getOuterOrderId());
                    netState.setOtherJson(gasOrder.getId());
                } else {
                    netState.setErrorCode(NetState.ERROR_OPERATE);
                    netState.setData("订单生成失败");
                }
            } else {
                netState.setErrorCode(NetState.SYSTEM_ERROR);
                netState.setData("订单生成异常");
            }
        } else {
            netState.setErrorCode(NetState.NODATA);
            netState.setData("未查询到相关油价信息");
        }

        return netState;
    }

    @RequestMapping(value = "/selectCallBack", method = {RequestMethod.POST, RequestMethod.GET})
    public @ResponseBody
    String refundOrder(String orderSn, String outerOrderId) {
        Map<String, Object> return_data = new HashedMap(); // 返回

        if (orderSn != null && outerOrderId != null) {
            GasOrder order = gasOrderService.selectByOrderSn(orderSn);
            if (order != null) {
                String status = "-1";
                switch (order.getPaystatus()) {
                    case 1:
                        status = "0";
                        break;
                    case 2:
                        status = "1";
                        break;
                    case 3:
                        status = "3";
                        break;
                    case 4:
                        status = "2";
                        break;
                }
                return_data.put("code", "200");
                return_data.put("message", "success");
                return_data.put("result", status);
            } else {
                return_data.put("code", "404");
                return_data.put("message", "error");
            }
        } else {
            return_data.put("code", "400");
            return_data.put("message", "fail");
        }

        return JSONObject.fromObject(return_data).toString();
    }

    @RequestMapping(value = "/refundOrder", method = {RequestMethod.POST, RequestMethod.GET})
    public @ResponseBody
    NetState refundOrder(String userId, String orderId, String remarks) {
        NetState netState = new NetState();
        System.out.println("开始退款：");
        if (userId == null || orderId == null) {
            netState.setErrorCode(NetState.PARAMS_ERROR);
            netState.setData("参数异常");
            return netState;
        }

        Subscribers sub = subscribersService.selectByPrimaryKey(userId);
        if (sub == null) {
            netState.setErrorCode(NetState.NODATA);
            netState.setData("数据异常");
            return netState;
        }
        //判断用户是否绑定支付宝
        Userpays userpays = userpaysService.selectByUserID(sub.getId(), true);
        if (userpays == null || userpays.getMobile() == null || userpays.getName() == null) {
            netState.setErrorCode(NetState.ZFB_NOT_BOUND);
            netState.setData("支付宝未绑定，请绑定支付宝");
            return netState;
        }
        // 获取token
        String token = null;
        String tokenResult = CZBPayUtils.createTokenAPI(Produce.getNowDate().getTime(), sub.getMobile());
        CZBPayToken czbToken = (CZBPayToken) JSONObject.toBean(JSONObject.fromObject(tokenResult), CZBPayToken.class);
        if (czbToken != null && czbToken.getCode() == 200) {
            token = czbToken.getResult().getToken();
        }

        GasOrder order = gasOrderService.selectByPrimaryKey(orderId);
        if (order != null) {
            if (order.getPaystatus() == 3 || order.getPaystatus() == 4) {
                netState.setErrorCode(NetState.PARAMS_ERROR);
                netState.setData("该订单退款中或已退款,请勿重复退款");
                return netState;
            }

            String payRefundResult = CZBPayUtils.getPayRefund(Produce.getNowDate().getTime(), token,
                    order.getCzbordersn(), order.getCzborderid(), order.getCzbouterorderid(),
                    order.getCzbpayamount().multiply(new BigDecimal(100)).intValue());

            PayRefund refund = (PayRefund) JSONObject.toBean(JSONObject.fromObject(payRefundResult), PayRefund.class);
            if (refund != null && refund.getCode() == 200) {
                order.setPaystatus(3);
                order.setRemark(remarks);
                int code = gasOrderService.updateByPrimaryKeySelective(order);
                if (code == 1) {
                    netState.setErrorCode(NetState.SUCCESS_CONN);
                    netState.setData("订单退款申请成功");
                    System.out.println("订单发起接口成功");
                } else {
                    netState.setErrorCode(NetState.ERROR_OPERATE);
                    netState.setData("订单退款申请失败");
                }
            } else {
                netState.setErrorCode(NetState.SYSTEM_ERROR);
                netState.setData("订单退款申请异常");
            }
        } else {
            netState.setErrorCode(NetState.NODATA);
            netState.setData("未查询到相订单");
        }
        return netState;
    }

    @RequestMapping(value = "/refundCallBack", method = {RequestMethod.POST, RequestMethod.GET})
    public @ResponseBody
    String refundCallBack(String orderSn, String refundTradeNo, String refundAmount, String outerOrderId) {
        Map<String, Object> return_data = new HashedMap(); // 返回

        if (orderSn != null) {
            GasOrder order = gasOrderService.selectByOrderSn(orderSn);
            if (order != null) {
                order.setPaystatus(5);
                int code = gasOrderService.updateByPrimaryKeySelective(order);
                if (code >= 1) {
                    return_data.put("code", "200");
                    return_data.put("message", "success");
                    return_data.put("result", "Order Refund Update Success");
                } else {
                    return_data.put("code", "500");
                    return_data.put("message", "fail");
                    return_data.put("result", "Order Refund Update Fail");
                }
            } else {
                return_data.put("code", "400");
                return_data.put("message", "warning");
                return_data.put("result", "Order Refund Pay Error");
            }
        } else {
            return_data.put("code", "404");
            return_data.put("message", "error");
            return_data.put("result", "Order Refund Query Error");
        }
        return JSONObject.fromObject(return_data).toString();
    }

    @RequestMapping(value = "/getOrder", method = {RequestMethod.POST, RequestMethod.GET})
    public @ResponseBody
    NetState getOrder(String userId, Integer pageNo) {
        NetState netState = new NetState();

        if (userId == null) {
            netState.setErrorCode(NetState.PARAMS_ERROR);
            netState.setData("参数异常");
            return netState;
        }

        Page page = new Page();
        page.setCurrentPageNo(pageNo);

        GasOrder order = new GasOrder();
        order.setUserid(userId);
        List<GasOrder> orders = null;
        page.setRecordTotal(gasOrderService.countByUserId(userId));
        orders = gasOrderService.selectByUserId(page, order);

        if (pageNo > page.getPageTotal()) {
            orders = null;
        }

        if (orders != null && orders.size() > 0) {
            netState.setJson(orders);
        }
        netState.setErrorCode(NetState.SUCCESS_CONN);
        netState.setData("查询成功");
        return netState;
    }

    @RequestMapping(value = "/getOrderDetails", method = {RequestMethod.POST, RequestMethod.GET})
    public @ResponseBody
    NetState getOrderDetails(String orderId) {
        NetState netState = new NetState();

        if (orderId == null) {
            netState.setErrorCode(NetState.PARAMS_ERROR);
            netState.setData("参数异常");
            return netState;
        }

        GasOrder order = gasOrderService.selectByPrimaryKey(orderId);
        if (order != null) {
            Gas gas = gasService.selectByPrimaryKey(order.getGasid());
            order.setGaspic(gas.getGaslogosmall());
            netState.setJson(order);
        }
        netState.setErrorCode(NetState.SUCCESS_CONN);
        netState.setData("查询成功");
        return netState;
    }

    @RequestMapping(value = "/getOrderMoney", method = {RequestMethod.POST, RequestMethod.GET})
    public @ResponseBody
    NetState getOrderPrice(String realmoney, String mobile, String gasId, String oilNo, String parentid) {
        NetState netState = new NetState();

        if (realmoney == null || realmoney.equals("") || mobile == null || mobile.equals("")) {
            netState.setErrorCode(NetState.PARAMS_ERROR);
            netState.setData("参数异常");
            return netState;
        }
        if (mobile == null || mobile.equals("")) {
            netState.setData("手机信息为空");
            netState.setErrorCode(NetState.PARAMS_ERROR);
            return netState;
        }
        Boolean isMobile = Produce.isMobile(mobile);
        if (!isMobile) {
            netState.setData("手机号码验证不正确");
            netState.setErrorCode(NetState.PARAMS_ERROR);
            return netState;
        }

        String token = null;
        Long date = Produce.getNowDate().getTime();
        String tokenResult = CZBPayUtils.createTokenAPI(date, mobile);
        CZBPayToken czbToken = (CZBPayToken) JSONObject.toBean(JSONObject.fromObject(tokenResult), CZBPayToken.class);
        if (czbToken != null && czbToken.getCode() == 200) {
            token = czbToken.getResult().getToken();
        }
        //重新获取油站信息
        GasOilprice gasOilprice = CZBOilUtil.getGasDetailApi(mobile, parentid, gasId, oilNo, token, date);
        if (gasOilprice == null) {
            netState.setErrorCode(NetState.ERROR_OPERATE);
            netState.setData("油站信息查询失败");
        }
        BigDecimal amountGun = new BigDecimal(realmoney);
        BigDecimal litre = amountGun.divide(gasOilprice.getPricegun(), 2, BigDecimal.ROUND_HALF_UP);

        // 计算车主帮实付
        BigDecimal czbPayAmount = amountGun.multiply(gasOilprice.getPriceyfq()).divide(gasOilprice.getPricegun(), 2, BigDecimal.ROUND_HALF_UP);

        Map<String, Object> resultMap = Maps.newHashMap();
        resultMap.put("czbPayAmount", czbPayAmount);
        resultMap.put("litre", litre);
        resultMap.put("freeMoney", amountGun.subtract(czbPayAmount).doubleValue());
        netState.setJson(resultMap);
        netState.setErrorCode(NetState.SUCCESS_CONN);
        netState.setData("查询成功");
        return netState;
    }

    /**
     * @Date: 2019/12/26 14:04
     * @Description: 返回H5调用接口，返回可直接调起H5支付的链接
     */
    @CrossOrigin
    @RequestMapping(value = "/recordUserBuy", method = {RequestMethod.POST, RequestMethod.GET})
    @ApiOperation(value = "api接口", notes = "H5支付前获取跳转链接的接口")
    public @ResponseBody
    NetState recordUserBuy(String parentid, String mobile, String gasId, String oilNum, String oilGun, String payMoney) {
        NetState netState = new NetState();
        String returnURL = "";
        try {
            List<Subscribers> sub=subscribersService.selectBySub(mobile,parentid);
            if (sub.size()<=0){
                netState.setData("用户不存在");
                netState.setErrorCode(NetState.ERROR_OPERATE);
                return netState;
            }

                Subscribers subscribers = sub.get(0);
                Users agent = usersService.selectByPrimaryKey(parentid);
                //如果是厦门通的 简单判断一下
                if (parentid.equals("8be9e1482e9f4125838993f478bac853")){
                    if (subscribers.getShopBalance() < 500) {
                        String results1 = VosHelper.GetVosAccount(
                                "{accounts:['" + agent.getAgentprefix() + subscribers.getMobile() + "']}");
                        VosModelList v21 = GsonUtil.getObject(results1, VosModelList.class);
                        if (v21 != null && v21.retCode == 0) {
                            InfoCustomers info2 = v21.infoCustomers[0];
                            if (info2.getMoney().compareTo(new BigDecimal(5)) < 1) {
                                netState.setData("用户加油金不足");
                                netState.setErrorCode(NetState.FEAILED);
                                return netState;
                            }
                        }
                    }
                }else if (parentid.equals("13715e2af9b24f55ab24773101688490") || parentid.equals("24bc36812eed4772ae7a18efab0e3048")){
                    //不做处理  如果是团拼宝
                }else{
                    String results1 = VosHelper.GetVosAccount(
                            "{accounts:['" + agent.getAgentprefix() + subscribers.getMobile() + "']}");
                    VosModelList v21 = GsonUtil.getObject(results1, VosModelList.class);
                    if (v21 != null && v21.retCode == 0) {
                        InfoCustomers info2 = v21.infoCustomers[0];
                        if (info2.getMoney().compareTo(new BigDecimal(5)) < 1) {
                            netState.setData("用户加油金不足");
                            netState.setErrorCode(NetState.FEAILED);
                            return netState;
                        }
                    }
                }
            String token = CZBTokenUtils.getNowToken(mobile);
            Long time = new Date().getTime();
            JSONArray result = CZBTokenUtils.getGasDetailsReal(time, gasId, mobile, token);
            if (result.size() > 0) {
                Object o = result.get(0);
                com.alibaba.fastjson.JSONObject jsonObject = com.alibaba.fastjson.JSONObject.parseObject(o.toString());
                String name = jsonObject.getString("gasName");
                String userid=subscribers.getId();
                redisCacheManager.set("userBuy:" + name + ":" + oilGun + ":" + parentid + ":" + mobile+":"+userid, gasId);
                redisCacheManager.expire("userBuy:" + name + ":" + oilGun + ":" + parentid + ":" + mobile+":"+userid, 1200);//设置这个超时时间为20分钟
                returnURL = CZBPayUtils.getCZBH5Url(mobile, gasId, oilGun);
                if (returnURL == null) return new NetState(NetState.FEAILED,"参数错误");
                netState.setErrorCode(NetState.SUCCESS_CONN);
                netState.setData("操作成功");
                netState.setJson(returnURL);
            }

        } catch (Exception e) {
            e.printStackTrace();
            log.error("加油H5接口调用失败",e);
            netState.setData("后台出问题了，QAQ");
            netState.setErrorCode(NetState.FEAILED);
        }
        return netState;
    }
}
